<?php

class CCoreNetImapStreamWrapper
{
	/**
	 * @var array
	 */
	static $_aParentStream = array();

	/**
	 * @var resourse
	 */
	private $_rStream;

	/**
	 * @var int
	 */
	private $iSize;

	/**
	 * @var int
	 */
	private $iPos;

	/**
	 * @param resource $rStream
	 * @param int $iLiteralLen
	 */
	public static function CreateLiteralStream($rStream, $iLiteralLen)
	{
		if (!in_array('ccoreimap', stream_get_wrappers()))
		{
			stream_wrapper_register('ccoreimap', 'CCoreNetImapStreamWrapper');
		}
		self::$_aParentStream[] = $rStream;
		return fopen('ccoreimap://'.$iLiteralLen.'/?id='.count(self::$_aParentStream), 'rb');;
	}

	/**
	 * @param string $sPath
	 * @param string $sMode
	 * @param int $iOptions
	 * @param string &$sOpenedPath
	 * @return bool
	 */
	public function stream_open($sPath, $sMode, $iOptions, &$sOpenedPath)
	{
		$aPath = parse_url($sPath);
		if (isset($aPath['host']) && is_numeric($aPath['host']))
		{
			if (isset($aPath['query']) && !empty($aPath['query']))
			{
				$aOutput = array();
				parse_str($aPath['query'], $aOutput);
				if (isset($aOutput['id']))
				{
					$iId = (int) $aOutput['id'];
					if (isset(self::$_aParentStream[--$iId]))
					{
						$this->_rStream = self::$_aParentStream[$iId];
					}
				}
			}

			$this->iSize = (int) $aPath['host'];
			$this->iPos = 0;
			return is_resource($this->_rStream);
		}
		return false;
	}

	/**
	 * @param int $iCount
	 * @return string
	 */
	public function stream_read($iCount)
	{
		if ($this->iSize < $this->iPos + $iCount)
		{
			$iCount = $this->iSize - $this->iPos;
		}

		if ($iCount > 0)
		{
			$sReadResult = fread($this->_rStream, $iCount);
			$this->iPos += strlen($sReadResult);
			return $sReadResult;
		}
		return false;
	}

	/**
	 * @param string $sData
	 * @return int
	 */
	public function stream_write($sData)
	{
		return 0;
	}

	/**
	 * @return int
	 */
	public function stream_tell()
	{
		return $this->iPos;
	}

	/**
	 * @return bool
	 */
	public function stream_eof()
	{
		return $this->iPos >= $this->iSize;
	}

	/**
	 *
	 * @return array
	 */
	public function stream_stat()
	{
		return array(
			'dev' => 2,
			'ino' => 0,
			'mode' => 33206,
			'nlink' => 1,
			'uid' => 0,
			'gid' => 0,
			'rdev' => 2,
			'size' => $this->iSize,
			'atime' => 1061067181,
			'mtime' => 1056136526,
			'ctime' => 1056136526,
			'blksize' => -1,
			'blocks' => -1
		);
	}

	/**
	 * @param int $iOffset
	 * @param int $iWhence
	 * @return bool
	 */
	public function stream_seek($iOffset, $iWhence)
	{
		return false;
	}
}
